from scapy.all import *
import time
import struct
import sys

def icmp_time_request(server_ip, timeout=2):
    # 生成随机 ID 和序列号（匹配请求与应答）
    icmp_id = random.randint(1, 65535)
    icmp_seq = random.randint(1, 65535)
    
    # 客户端发送时间戳（单位：毫秒，取低 32 位）
    send_ts = int(time.time() * 1000) & 0xFFFFFFFF
    # 构建 ICMP Timestamp Request 报文（类型 13）
    packet = IP(dst=server_ip)/ICMP(type=13, id=icmp_id, seq=icmp_seq)/\
             Raw(load=struct.pack("!III", send_ts, 0, 0))  # 后两个时间戳占位
    
    # 发送请求并等待应答
    reply = sr1(packet, timeout=timeout, verbose=0)
    
    if not reply or ICMP not in reply or reply[ICMP].type != 14:
        print("未收到有效应答")
        return
    
    # 解析应答中的时间戳
    send_ts, recv_ts, trans_ts = struct.unpack("!III", reply[Raw].load)
    client_recv_ts = int(time.time() * 1000)  # 客户端接收应答的时间
    
    # 计算网络延迟和服务器时间
    rtt = client_recv_ts - send_ts  # 往返时间（毫秒）
    server_time = trans_ts + (rtt // 2)  # 估算服务器当前时间（补偿网络延迟）
    
    # 打印结果
    print(f"服务器 {server_ip} 时间信息：")
    print(f"客户端发送时间：{time.ctime(send_ts / 1000)}")
    print(f"服务器接收时间：{time.ctime(recv_ts / 1000)}")
    print(f"服务器发送时间：{time.ctime(trans_ts / 1000)}")
    print(f"客户端接收时间：{time.ctime(client_recv_ts / 1000)}")
    print(f"往返延迟：{rtt} 毫秒")
    print(f"估算服务器当前时间：{time.ctime(server_time / 1000)}")

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print(f"用法：{sys.argv[0]} <服务器IP>")
        sys.exit(1)
    server_ip = sys.argv[1]
    icmp_time_request(server_ip)